#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>          
#include <sys/wait.h>
#include <signal.h>

#define Linux011 1
#ifdef Linux011
#define   __LIBRARY__
#include <unistd.h>
#include <stdlib.h>

#define _syscall_p2(type,name,atype,a,btype,b) \
type name(atype a,btype b) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
	: "=a" (__res) \
	: "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b))); \
return (type) __res; \
}
static inline _syscall_p2(sem_t *,sem_open,const char *,name,unsigned int,value)
static inline _syscall1(int,sem_wait,sem_t *,sem)
static inline _syscall1(int,sem_post,sem_t *,sem)
static inline _syscall1(int,sem_unlink,const char *,name)
#else
#include <semaphore.h>
#include <sys/stat.h>       
#include <unistd.h>
#endif

#define FILE_BUF "./pc.buf"
#define BUFSIZE 10
int  buf_out = 0;  
int  buf_in = 0; 

sem_t * empty,* full,* mutex;
int i,fd,data=0,ppid[6];

int main()
{

#ifdef Linux011
    empty = sem_open("empty",3);
    full = sem_open("full",0);
    mutex = sem_open("mutex",1);
#else
    empty = sem_open("empty",O_CREAT,0666,3);
    full = sem_open("full",O_CREAT,0666,0);
    mutex = sem_open("mutex",O_CREAT,0666,1);
#endif
    fd = open(FILE_BUF,O_CREAT|O_TRUNC|O_RDWR,0666);

    if(!(ppid[0] = fork())){ 
        for (i = 0; i < 500; i++)
        {
            sem_wait(empty);
            sem_wait(mutex);
            /*写入数据*/
            lseek(fd, buf_in*sizeof(int), SEEK_SET); 
            write(fd,(char *)&i,sizeof(int));
            /*记录写入位置*/
            buf_in = (buf_in + 1) % BUFSIZE;
            sem_post(mutex);
            sem_post(full);
        }
    }
    for (i = 1; i < 6; i++)
    {
        if(!(ppid[i] =fork())){
            
            while(1)
            {
                sem_wait(full);
                sem_wait(mutex);
                /* 获取读取位置 */
                lseek(fd,BUFSIZE*sizeof(int),SEEK_SET);
                read(fd,(char *)&buf_out,sizeof(int));
                /* 读取数据 */
                lseek(fd,buf_out*sizeof(int),SEEK_SET);
                read(fd,(char *)&data,sizeof(int));   
                /* 记录读取位置 */             
                buf_out = (buf_out + 1) % BUFSIZE;
                lseek(fd,BUFSIZE*sizeof(int),SEEK_SET);
                write(fd,(char *)&buf_out,sizeof(int));
                printf("%d:%d\n",getpid(),data);
                fflush(stdout);
                if(data == 499)  _exit(0);
                sem_post(mutex);
                sem_post(empty);
            }
        }
    }
    wait(NULL);
    for (i = 0; i < 6; i++)
        kill(ppid[i],SIGKILL);
    sem_unlink("empty");
    sem_unlink("mutex");
    sem_unlink("full");
    close(fd);
    return 0;
}
